package match_grpc

import (
	"context"
	"errors"
	"log"
	"match-server/pvp"
	"match-server/pvp/dto"
	pb "pb/proto"
	"time"
)

type MatcherGrpcService struct {
	pb.UnimplementedMatcherGrpcServiceServer
}

// 测试匹配
func (s *MatcherGrpcService) Match(ctx context.Context, req *pb.GrpcMatchReq) (*pb.GrpcMatchRes, error) {
	matchType := req.GetMatchType()

	matcher := dto.DefaultMatcher{
		MatchType: int(matchType),
		MatcherId: int(req.PlayerId),
		Score:     int(req.Capacity),
		Time:      time.Now(),
	}
	resultsChan, err := pvp.GlobalMatchMgr.AddMatcher(int(matchType), matcher)
	if err != nil {
		log.Printf("加入匹配队列错误: %v, 玩家ID: %d", err, req.PlayerId)
		// 返回具体的错误信息给客户端
		// 根据 pvp.ErrAlreadyInQueue 判断是否是重复加入
		if errors.Is(err, pvp.ErrAlreadyInQueue) {
			return &pb.GrpcMatchRes{State: 0, Msg: "您已在匹配队列中"}, nil
		}
		return &pb.GrpcMatchRes{State: 0, Msg: "加入匹配队列失败"}, nil
	}

	// 等待匹配结果或上下文取消
	select {
	case <-ctx.Done():
		// gRPC 请求的上下文被取消 (例如客户端断开连接)
		log.Printf("客户端取消了请求或连接断开，玩家ID: %d", req.PlayerId)
		// 尝试取消该玩家在匹配服务中的匹配
		err := pvp.GlobalMatchMgr.CancelMatch(int(matchType), matcher.MatcherId)
		if err != nil {
			log.Printf("尝试取消玩家 %d 的匹配时出错: %v", matcher.MatcherId, err)
		}
		return &pb.GrpcMatchRes{State: 0, Msg: "请求已取消"}, nil
	case result, ok := <-resultsChan:
		if !ok {
			log.Printf("匹配结果通道意外关闭，玩家ID: %d", req.PlayerId)
			return &pb.GrpcMatchRes{State: 0, Msg: "匹配服务内部错误"}, nil
		}

		if result.Success {
			log.Printf("匹配成功，玩家ID: %d, 房间ID: %d", req.PlayerId, result.RoomId)
			// todo 调用battle-server创建房间并获取房间号, 并给出一个token到战斗服，后续验证前端直连的正确性

			return &pb.GrpcMatchRes{State: 1, RoomId: int32(result.RoomId)}, nil
		} else {
			// 匹配失败或超时 (AddMatcher 会处理超时并返回 Success=false)
			log.Printf("匹配失败或超时，玩家ID: %d", req.PlayerId)
			// 可以根据 result 中的具体错误信息返回更详细的 Msg
			return &pb.GrpcMatchRes{State: 0, Msg: "匹配失败或超时"}, nil
		}
	}
}
